	#include <sys/mman.h>
	#include <sys/stat.h>
	#include <fcntl.h>
	#include <stdio.h>
	#include <stdlib.h>
	#include <unistd.h>
	#include <string.h>
	#include "logger.h"

# define MAX 2560 // (10 кбайт)

int write_numbers_to_tmp_file(char *addr, FILE *fltemp, int length) //записывает числа в инт массив по 3 штуки
{
	int n, i=0, l=0; 
	int arr[MAX]; 
	char *pv;
	pv=addr;
	int j, k;
	ssize_t tmp;

	n=length;

	while(i<n)
	{
		arr[i]=atoi(pv);
		pv=strchr(pv, ' ');
		i++;
		l++;
		if (pv==NULL) break;
		pv++;
		if (i==MAX)
		{
			k=fseek(fltemp,0,SEEK_END);
			if (k != 0)
			{
				logm("Error in fseeking input file", "");
				return -1;
			}
			tmp = fwrite(&arr, i*sizeof(int), 1, fltemp);
			if (tmp < 1)
			{
				logm("Error in writing to tmp array", "");
				return -1;
			}
			n=n-i;
			i=0;
		}
	}
	if (i!=0)
	{
		k=fseek(fltemp,0,SEEK_END);
		if (k != 0)
		{
			logm("Error in fseeking input file", "");
			return -1;
		}
		tmp = fwrite(&arr, i*sizeof(int), 1, fltemp);
		if (tmp < 1)
		{
			logm("Error in writing to tmp array", "");
			return -1;
		}
	}
return l;}// l = number of digits

int compare (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}

int main(int argc, char *argv[])
{
	char *addr;
	int *taddr;
	int fdinput, fdtemp, j, l;
	ssize_t s;
	FILE *floutput, *fltemp;
	struct stat sb;
	struct timeval timenow;

	gettimeofday(&timenow, NULL);
	printf("Begin:       %u sec, %u msec\n", (int)timenow.tv_sec, (int)timenow.tv_usec);


	if (logstart("Sort") == -1) return -1;

	if (argc != 3)
	{
		logm("Not 2 arguments", "");
		logend();
		return -1;
	}
	fdinput = open(argv[1], O_RDONLY);
	if (fdinput == -1)
	{
		logm("Error opening input file", "");
		logend();
		return -1;
	}
	if (fstat(fdinput, &sb) == -1)           /* To obtain file size */
	{
		logm("Error geting info of the input file", "");
		logend();
		return -1;
	}
	if (sb.st_size > 4290000000)
	{
		logm("Error: the input file is too long", "");
		logend();
		return -1;
	}
	if (sb.st_size == 0)
	{
		logm("Error: the input file is empty", "");
		logend();
		return -1;
	}
	addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fdinput, 0);//SHARED?
	if (addr == MAP_FAILED)
	{
		logm("Error mapping input file", "");
		logend();
		return -1;
	}

	//create tmp file, write numbers to it (as int)
	fltemp = fopen("tmpsort.txt","w");
	if (fltemp == NULL)
	{
		logm("Error opening tmp file", "");
		logend();
		return -1;
	}

	l=write_numbers_to_tmp_file(addr, fltemp, sb.st_size);
	if (l == -1 )
	{
		logm("Error in getting numbers from input file", "");
		logend();
		return -1;
	}
	if (l == 0 )
	{
		logm("Error there are no numbers in input file", "");
		logend();
		return -1;
	}
	if (0 != munmap(addr, sb.st_size))
	{
		logm("Error unmapping input file", "");
		logend();
		return -1;
	}
	if (close(fdinput) != 0)
	{
		logm("Error closing input file", "");
		logend();
		return -1;
	}
	if (fclose(fltemp) != 0)
	{
		logm("Error closing tmp file", "");
		logend();
		return -1;
	}

	//maping tmp
	fdtemp = open("tmpsort.txt", O_RDWR);
	if (fdtemp == -1)
	{
		logm("Error opening tmp file", "");
		logend();
		return -1;
	} 
	if ( ((l+1)*4) > 4290000000)
	{
		logm("Error: the input file is too long", "");
		logend();
		return -1;
	}
	taddr = mmap(NULL, (l+1)*4, PROT_READ | PROT_WRITE, MAP_PRIVATE, fdtemp, 0);
	if (taddr == MAP_FAILED)
	{
		logm("Error mapping tmp file", "");
		logend();
		return -1;
	}

	gettimeofday(&timenow, NULL);
	printf("Before sort: %u sec, %u msec\n", (int)timenow.tv_sec, (int)timenow.tv_usec);
	//qsort
	qsort (taddr, l, sizeof(int), compare);
	gettimeofday(&timenow, NULL);
	printf("Arter sort:  %u sec, %u msec\n", (int)timenow.tv_sec, (int)timenow.tv_usec);

	//write to output file
	floutput = fopen(argv[2],"w");
	if (floutput==NULL)
	{
		logm("Error opening output file", "");
		logend();
		return -1;
	}
	for (j=0; j<l; j++)
	{
		if (0 > (fprintf(floutput, "%d ", taddr[j])))
		{
			logm("Error printing to output file", "");
			logend();
			return -1;
		}
	}
	//closing everything
	if (0 != munmap(taddr, (l+1)*4))
	{
		logm("Error unmapping tmp file", "");
		logend();
		return -1;
	}
	if (close(fdtemp) != 0)
	{
		logm("Error closing tmp file", "");
		logend();
		return -1;
	}
	if (fclose(floutput) != 0)
	{
		logm("Error closing output file", "");
		logend();
		return -1;
	}
	if (logend() == -1) return -1;

	gettimeofday(&timenow, NULL);
	printf("Final:       %u sec, %u msec\n", (int)timenow.tv_sec, (int)timenow.tv_usec);
	return 0;
}
